package Api.AliPay.Payment;

import Util.HttpUtil;
import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static Util.Tools.MaptoStr;
import static Util.Tools.getMD5;
import static org.apache.http.util.TextUtils.isEmpty;

/**
 * 支付宝小程序支付
 */
public class AliXcxPay {
    public static void main(String[] args) {
        try {
            // 目标URL
            String url = "https://pay.heepay.com/Payment/Index.aspx";
            //MD5密钥，商户后台网关密钥下面第一个
            String key = "651886F030134F848F548A12";
            //商户编号，（汇付宝商户内码：七位整数数字）
            String agent_id = "1664502";
            //子商户号（大商户子户模式传参），传了必须参与签名放在key后面
            String ref_agent_id ="";
            // 获取当前14位时间戳
            Date now = new Date();
            // 创建 SimpleDateFormat 对象，指定日期格式
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String timestamp = dateFormat.format(now);

            //固定版本号
            String version ="1";
            //是否使用手机触屏版，1=是
            String is_phone = "1";
            //是否触屏内嵌页，1=是
            String is_frame = "1";
            String pay_type = "22";
            String agent_bill_id = timestamp;
            String agent_bill_time = timestamp;
            String pay_amt = "0.01";
            /*
            支付后的异步地址，URL参数是以http://或https://开头的完整URL地址(后台处理)，提交的url地址必须外网能访问到，否则无法通知商户。值可以为空，但不可以为null。
             */
            String notify_url = "https://www.baidu.com/";
            String return_url = "https://www.baidu.com/";
            String user_ip = "127_127_12_12";
            String goods_num = "1";
            String goods_name = "商品名称";
            String goods_name1= URLEncoder.encode(goods_name, "GBK");
            //买家支付宝账户或者user_id  必须传对
            String remark = "16638029747";
            String goods_note = "支付说明,比如购买商品";
            String goods_note1= URLEncoder.encode(goods_note, "GBK");

            /**
             meta_option={"is_minipg":"1","ut":"张三","uc":"140511199409163000"，"is_guarantee":"1"}汉字编码GBK，需要base64。is_minipg是必传的，传uc和ut只允许此用户支付，is_guarantee=1 代表分润单，meta_option不需要参与签名
             */

            Map<String, String> map = new HashMap<String, String>();
            map.put("is_guarantee","1");
            map.put("is_minipg","1");
            String a = JSON.toJSONString(map);
            // Step 1: 将JSON串编码为GBK格式的字节数组
            byte[] gbkBytes;
            try {
                gbkBytes = a.getBytes("GBk");
            } catch (UnsupportedEncodingException e) {
                System.out.println("不支持的字符集：" + e.getMessage());
                return;
            }
            // Step 2: 对GBK格式的字节数组进行Base64编码
            String base64EncodedString = Base64.getEncoder().encodeToString(gbkBytes);

            String meta_option = URLEncoder.encode(base64EncodedString);



            Map<String, String> parameters = new HashMap<String, String>();
            if (isEmpty(ref_agent_id)) {
                //拼接待加密参数
                StringBuilder builder = new StringBuilder();
                builder.append("version=");
                builder.append(version);
                builder.append("&agent_id=");
                builder.append(agent_id);
                builder.append("&agent_bill_id=");
                builder.append(agent_bill_id);
                builder.append("&agent_bill_time=");
                builder.append(agent_bill_time);
                builder.append("&pay_type=");
                builder.append(pay_type);
                builder.append("&pay_amt=");
                builder.append(pay_amt);
                builder.append("&notify_url=");
                builder.append(notify_url);
                builder.append("&return_url=");
                builder.append(return_url);
                builder.append("&user_ip=");
                builder.append(user_ip);
                builder.append("&key=");
                builder.append(key);

                String Date = builder.toString();
                //MD5加密得出签名结果
                String sign = getMD5(Date);


                parameters.put("version", version);
                parameters.put("is_phone", is_phone);
                parameters.put("is_frame", is_frame);
                parameters.put("pay_type", pay_type);
                parameters.put("agent_id", agent_id);
                parameters.put("agent_bill_id", agent_bill_id);
                parameters.put("agent_bill_time", agent_bill_time);
                parameters.put("pay_amt", pay_amt);
                parameters.put("notify_url", notify_url);
                parameters.put("return_url", return_url);
                parameters.put("user_ip", user_ip);
                parameters.put("goods_name", goods_name1);
                parameters.put("goods_num", goods_num);
                parameters.put("remark", remark);
                parameters.put("goods_note", goods_note1);
                parameters.put("meta_option", meta_option);
                parameters.put("sign", sign);
            }else {
                //拼接待加密参数
                StringBuilder builder = new StringBuilder();
                builder.append("version=");
                builder.append(version);
                builder.append("&agent_id=");
                builder.append(agent_id);
                builder.append("&agent_bill_id=");
                builder.append(agent_bill_id);
                builder.append("&agent_bill_time=");
                builder.append(agent_bill_time);
                builder.append("&pay_type=");
                builder.append(pay_type);
                builder.append("&pay_amt=");
                builder.append(pay_amt);
                builder.append("&notify_url=");
                builder.append(notify_url);
                builder.append("&return_url=");
                builder.append(return_url);
                builder.append("&user_ip=");
                builder.append(user_ip);
                builder.append("&key=");
                builder.append(key);
                builder.append("&ref_agent_id=");
                builder.append(ref_agent_id);

                String Date = builder.toString();
                //MD5加密得出签名结果
                String sign = getMD5(Date);


                parameters.put("version", version);
                parameters.put("is_phone", is_phone);
                parameters.put("is_frame", is_frame);
                parameters.put("pay_type", pay_type);
                parameters.put("agent_id", agent_id);
                parameters.put("ref_agent_id", ref_agent_id);
                parameters.put("agent_bill_id", agent_bill_id);
                parameters.put("agent_bill_time", agent_bill_time);
                parameters.put("pay_amt", pay_amt);
                parameters.put("notify_url", notify_url);
                parameters.put("return_url", return_url);
                parameters.put("user_ip", user_ip);
                parameters.put("goods_name", goods_name1);
                parameters.put("goods_num", goods_num);
                parameters.put("remark", remark);
                parameters.put("goods_note", goods_note1);
                parameters.put("meta_option", meta_option);
                parameters.put("sign", sign);

            }

            //打印请求参数
            String Str = MaptoStr(parameters);
            System.out.println("发送请求数据：-------------------------------->"+ Str);

            String Result = HttpUtil.sendPost2(url, parameters);
            System.out.println("返回响应数据：-------------------------------->"+Result);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
